from flask import flash, redirect, url_for, render_template, request
from flask_login import login_required, current_user
from sqlalchemy import desc, or_
from app import db
from app.forms.book import DriftForm
from app.libs.email import send_email
from app.models.drift import Drift
from app.models.gift import Gift
from app.models.user import User
from app.models.wish import Wish
from app.view_models.drift import DriftCollection
from . import web
from app.libs.enums import PendingStatus


@web.route('/drift/<int:gid>', methods=['GET', 'POST'])
@login_required
def send_drift(gid):
    # 查询出礼物对象
    current_gift = Gift.query.get_or_404(gid)
    # 判断当前礼物是不是我赠送的
    if current_gift.is_youself_gift(current_user.id):
        flash('请不要自己赠送自己')
        return redirect(url_for('web.book_detail', isbn=current_gift.isbn))
    # TODO 如果一个用户在没收到礼物的时候,可以无限制的要礼物.这个判断有一些问题.
    can = current_user.can_send_drift()
    if not can:
        return render_template('not_enough_beans.html', beans=current_user.beans)

    # 保存交易的信息
    form = DriftForm(request.form)
    if request.method == 'POST' and form.validate():
        save_drift(form, current_gift)
        send_email(current_gift.user.email, '有人想要一本书', 'email/get_gift.html', wisher=current_user, gift=current_gift)
        return redirect(url_for('web.pending'))

    gifter = current_gift.user.summary
    return render_template('drift.html', gifter=gifter, user_beans=current_user.beans, form=form)


@web.route('/pending')
@login_required
def pending():
    # 查询我作为赠送者 or 接受者的交易信息
    drift = Drift.query.filter(or_(Drift.requester_id == current_user.id,
                                   Drift.gifter_id == current_user.id)).\
                                   order_by(desc(Drift.create_time)).all()
    views = DriftCollection(drift, current_user.id)
    return render_template('pending.html', drifts=views.data)


@web.route('/drift/<int:did>/reject')
@login_required
def reject_drift(did):
    with db.auto_commit():
        drift = Drift.query.filter(Drift.id == did, Drift.gifter_id == current_user.id).first_or_404()
        drift.pending = PendingStatus.Reject.value
        requester = User.query.get_or_404(drift.requester_id)
        requester.beans += 1
    return redirect(url_for('web.pending'))


@web.route('/drift/<int:did>/redraw')
@login_required
def redraw_drift(did):
    with db.auto_commit():
        current_drift = Drift.query.filter_by(requester_id=current_user.id, id=did).first_or_404()
        current_drift.pending = PendingStatus.Redraw.value
        # 撤销以后 <。)#)))≦豆+1
        current_user.beans += 1
    return redirect(url_for('web.pending'))


@web.route('/drift/<int:did>/mailed')
def mailed_drift(did):
    with db.auto_commit():
        # 当前交易状态修改成邮寄,并把<。)#)))≦豆+1
        drift = Drift.query.filter_by(gifter_id=current_user.id, id=did).first_or_404()
        drift.pending = PendingStatus.Success.value
        current_user.beans += 1
        # 赠送者 赠送清单修改,状态变为成功,并取消展示
        gift = Gift.query.filter_by(id=drift.gift_id).first_or_404()
        gift.launched = True
        # 因为图书已经赠送出去了,所以把请求者的心愿清单状态改为成功,并取消展示
        wish = Wish.query.filter_by(isbn=drift.isbn, uid=drift.requester_id, launched=False).first_or_404()
        wish.launched = True
    return redirect(url_for('web.pending'))


def save_drift(form, current_gift):
    with db.auto_commit():
        drift = Drift()
        # 将form下的所有属性保存到drift对象中(前提是模型类属性 == form下的类属性)
        form.populate_obj(drift)

        drift.requester_id = current_user.id # 接受用户id
        drift.recipient_name = current_user.nickname # 接受者昵称

        drift.gift_id = current_gift.id # 赠送礼物id
        drift.gifter_nickname = current_gift.user.nickname # 赠送书籍用户昵称
        drift.gifter_id = current_gift.user.id # 赠送书籍用户id

        book = current_gift.book # 拿到书籍信息.
        drift.book_title = book['title']
        drift.book_author = '-'.join(book['author'])
        drift.book_img = book['image']
        drift.isbn = book['isbn']

        current_user.beans -= 1

        db.session.add(drift)